package com.zxmr.utility.action;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.zxmr.action.Request;
import com.zxmr.action.Response;
import com.zxmr.action.ResponsePayload;
import com.zxmr.action.ResultCode;
import com.zxmr.domain.account.Role;
import com.zxmr.domain.file.Folder;
import com.zxmr.domain.file.ResourceAction;
import com.zxmr.domain.file.ResourceAuthorization;
import com.zxmr.domain.file.ResourceLevel;
import com.zxmr.domain.file.ResourceType;
import com.zxmr.domain.service.AuthorizationService;
import com.zxmr.domain.service.ResourceQueryBean;
import com.zxmr.domain.service.ResourceService;
import com.zxmr.navigate.ExecuteException;
import com.zxmr.navigate.Executor;
import com.zxmr.util.ResourceManager;
import com.zxmr.util.Utils;

public class ResourceAuthAction extends Executor {

	enum method{
		query,
		update
	}
	@Override
	public void execute(Request request, Response response) {
		try
		{
			method m = Enum.valueOf(method.class, this.getElement().getMethod());
			switch(m)
			{
			case query:
				query(request,response);
				break;
			case update:
				update(request,response);
				break;
			}
		}catch(Exception e)
		{
			ResponsePayload payload = new ResponsePayload();
			if(e instanceof ExecuteException)
			{
				payload.setValue(e.getMessage());
			}else
			{
				e.printStackTrace();
				payload.setValue("internal error");
			}
			response.setPayload(payload);
			response.setResult(ResultCode.COMPONENT_ERROR);
		}
		
	}

	private void update(Request request,Response response)throws ExecuteException
	{
		long folder = getFolder(request);
		int role = getRole(request);
		String action = request.getRequestParameters().get("action");
		String enabled = request.getRequestParameters().get("enabled");
		
		if(folder <= 0 || role <= 0 || Utils.isStringEmptyWithTrim(action))
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.invalid.parameter"));
		
		// check authorization
		authFolder(folder,request.getAccount().getCompany());
		
		ResourceService service = new ResourceService();
		
		ResourceAuthorization ra = new ResourceAuthorization();
		ra.setRole(role);
		ra.setResourceId(folder);
		ra.setResourceType(ResourceType.Folder);
		ra.setCompany(request.getAccount().getCompany());
		
		try
		{
			ra.setAction(Enum.valueOf(ResourceAction.class, action));
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.invalid.parameter"));
		}
		if("true".equals(enabled))
		{
			if(!service.addResourceAuth(ra))
				this.internalErrorResponse(response);
		}else
		{
			if(!service.deleteResourceAuth(ra))
				this.internalErrorResponse(response);
		}
		
		
	}
	private void authFolder(long folder,int company)throws ExecuteException
	{
		ResourceService service = new ResourceService();
		Folder f = service.queryFolder(folder, company);
		
		if(f == null)
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.folder.empty"));
		if(f.getLevel() != ResourceLevel.Protected)
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.folder.auth.noneed"));
	}
	private long getFolder(Request request)throws ExecuteException
	{
		try
		{
			return Long.parseLong(request.getRequestParameters().get("folder"));
			
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.invalid.parameter"));
		}
	}
	private int getRole(Request request)throws ExecuteException
	{
		try
		{
			return Integer.parseInt(request.getRequestParameters().get("role"));
			
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.invalid.parameter"));
		}
	}
	private void query(Request request,Response response)throws ExecuteException
	{
		long id = getID(request);
		
		authFolder(id,request.getAccount().getCompany());
		
		ResourceQueryBean queryBean = new ResourceQueryBean();
		queryBean.setCompany(request.getAccount().getCompany());
		queryBean.setResourceId(id);
		queryBean.setResourceType(ResourceType.Folder);
		
		ResourceService service = new ResourceService();
		List<ResourceAuthorization> ras = service.queryAuthForFolder(queryBean);
		
		AuthorizationService roleService = new AuthorizationService();
		List<Role> roles = roleService.queryAllRole(request.getAccount().getCompany());
		
		Collection<Map<String,Object>> dto = convertToDTO(ras,roles);
		
		ResponsePayload payload = new ResponsePayload(JSON.toJSONString(dto));
		response.setPayload(payload);
	}
	private Collection<Map<String,Object>> convertToDTO(List<ResourceAuthorization> ras,List<Role> roles)
	{
		if(ras == null)return null;
		
		Map<Integer,Map<String,Object>> temp = new HashMap<Integer,Map<String,Object>>();
		
		for(Role role : roles)
		{
			Map<String,Object> dto = null;
			dto = new HashMap<String,Object>();
			dto.put("roleName", role.getName());
			dto.put("role", role.getId());
			temp.put(role.getId(), dto);
		}
		for(ResourceAuthorization ra : ras)
		{
			int role = ra.getRole();
			Map<String,Object> dto = temp.get(role);
			dto.put(ra.getAction().name(), "true");
		}
		
		return temp.values();
	}
	private long getID(Request request)throws ExecuteException
	{
		try
		{
			return Long.parseLong(request.getRequestParameters().get("id"));
			
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.utility.invalid.parameter"));
		}
	}
	
}
